<template>
  <div>
    <q-form class="q-gutter-md dialog-content" style="height: 567px">
      <div class="container">
        <div class="detail-container flex">
          <div class="margin-r-20">网关序列号: {{ driverParams.gatewaySN || '-' }}</div>
          <div class="margin-r-20">网关型号: {{ driverParams.productName || '-' }}</div>
          <div class="margin-r-20 ellipsis" style="width: 300px">驱动: {{ driverConfigData.driverName || '-' }}</div>
        </div>
        <q-separator />
        <PointTable :deviceIds="deviceIds" @changeData="changeTableData" @changeDeviceType="changeDeviceType" @changeDeviceIds="changeDeviceIds"/>
      </div>
      <q-separator />
      <div class="dialog-footer text-center margin-t-10">
        <q-btn outline label="取消" color="primary" @click="hideDialog" class="q-mr-md"/>
        <q-btn unelevated :label="isCompete ? '完成': '下一步'" color="primary" @click="submit" :loading="submitting"/>
        <span v-if="!isCompete" style="color: #999999;cursor: pointer" class="margin-l-20" @click="skipBind">跳过</span>
      </div>
    </q-form>
  </div>
</template>

<script>
import PointTable from './point-table'
import { plcDeviceBindPoint, plcPointConfigSet } from '../../../../../boot/miot/plc-list'
import _ from 'lodash'
import { commonAlarmhList, commonAlarmlList, commonPointList } from './constant'

export default {
  name: 'point-config',
  components: {
    PointTable
  },
  props: {
    driverConfigData: {
      type: Object,
      default: () => {}
    },
    driverParams: {
      type: Object,
      default: () => {}
    },
    deviceIds: {
      type: Array,
      default: () => []
    },
    isCompete: {
      type: Boolean,
      default: false
    }
  },
  data () {
    return {
      submitting: false,
      tableData: [],
      deviceTypeOptions: [],
      newDeviceIds: []
    }
  },
  computed: {
    // 通用物模型
    commonDeviceType () {
      return this.deviceTypeOptions.filter(item => item.common === 1)
    }
  },
  methods: {
    async submit () {
      // 校验是否添加了点位
      if (this.tableData.length === 0) {
        this.$message.warning('请添加点位')
        return
      }

      // 校验每个设备必须包含一个DevPower,且必须有一个H或者L

      // 上报类型的type, key为设备编号,value为DevPower数量
      const deviceTypeMap = new Map()
      const reportTypeMapHL = new Map()
      const reportTypeMapReal = new Map()
      // 循环所有设备
      this.tableData.forEach(item => {
        // 物模型唯一性
        const valueProduct = {
          productId: item.productId,
          count: 0
        }
        const currentProduct = deviceTypeMap.get(item.deviceNum)
        if (item.productId && currentProduct && currentProduct.productId !== item.productId) {
          valueProduct.count = currentProduct.count + 1
          deviceTypeMap.set(item.deviceNum, valueProduct)
        } else if (!currentProduct) {
          valueProduct.count = 1
          deviceTypeMap.set(item.deviceNum, valueProduct)
        }
        let currentHLCount = reportTypeMapHL.get(item.deviceNum)
        if (currentHLCount !== undefined) {
          if (item.repType === '1' && (item.serviceTypeId === 'H' || item.serviceTypeId === 'L')) {
            reportTypeMapHL.set(item.deviceNum, currentHLCount + 1)
          }
        } else {
          if (item.repType === '1' && (item.serviceTypeId === 'H' || item.serviceTypeId === 'L')) {
            reportTypeMapHL.set(item.deviceNum, 1)
          } else {
            reportTypeMapHL.set(item.deviceNum, 0)
          }
        }
        // 状态
        if (item.repType === '4') {
          // 实时数据唯一性
          const key = item.deviceNum + item.repName
          const value = {
            deviceNum: item.deviceNum,
            repName: item.repName,
            count: 0
          }
          let currentReal = reportTypeMapReal.get(key)
          if (currentReal && currentReal.count !== 0) {
            value.count = currentReal.count + 1
            reportTypeMapReal.set(key, value)
          } else {
            value.count = 1
            reportTypeMapReal.set(key, value)
          }
        }
      })

      // 构造提示消息,如果设备中含有0或者大于1的DevPower,则报错
      let message = ''
      for (let [key, val] of deviceTypeMap.entries()) {
        if (val.count > 1) {
          message = `设备编号${key}含有多个物模型`
          break
        }
      }

      for (let [key, val] of reportTypeMapHL.entries()) {
        if (val === 0) {
          message = `设备编号${key}状态不存在H或者L,请设置H或者L`
          break
        } else if (val > 1) {
          message = `设备编号${key}状态含有多个H或者L,请设置一个H或者L`
          break
        }
      }

      // eslint-disable-next-line no-unused-vars
      for (let [key, val] of reportTypeMapReal.entries()) {
        if (val && val.count > 1) {
          message = `设备编号"${val.deviceNum}"上报名称为"${val.repName}"重复`
          break
        }
      }

      // 弹出提示信息, 并终止
      if (message) {
        this.$message.error(message)
        return
      }

      // 选择通用物模型的设备id
      const commonDeviceIds = []
      if (this.commonDeviceType?.length > 0) {
        this.tableData.forEach(item => {
          const index = this.commonDeviceType.findIndex(common => common.value === item.productId)
          if (index > -1 && commonDeviceIds.indexOf(item.deviceId) === -1) {
            commonDeviceIds.push(item.deviceId)
          }
        })
      }

      const usePointObj = {}
      const commonPointObj = {}
      const useAlarmlObj = {}
      const commonAlarmlObj = {}
      const useAlarmhObj = {}
      const commonAlarmhObj = {}
      if (commonDeviceIds.length > 0) {
        commonDeviceIds.forEach(item => {
          usePointObj[item] = []
          commonPointObj[item] = []
          useAlarmlObj[item] = []
          commonAlarmlObj[item] = []
          useAlarmhObj[item] = []
          commonAlarmhObj[item] = []
        })

        this.tableData.forEach(item => {
          // 报警H
          if (item.repType === '3' && item.serviceTypeId === 'H' && item.relaPoint) {
            useAlarmhObj[item.deviceId].push(item.relaPoint)
          }
          // 报警L
          if (item.repType === '3' && item.serviceTypeId === 'L' && item.relaPoint) {
            useAlarmlObj[item.deviceId].push(item.relaPoint)
          }
          // 实时数据
          if (item.repType === '4' && item.relaPoint) {
            usePointObj[item.deviceId].push(item.relaPoint)
          }
        })

        commonDeviceIds.forEach(item => {
          const usePointData = usePointObj[item]
          commonPointObj[item] = _.difference(commonPointList, usePointData)

          const useAlarmlData = useAlarmlObj[item]
          commonAlarmlObj[item] = _.difference(commonAlarmlList, useAlarmlData)

          const useAlarmhData = useAlarmhObj[item]
          commonAlarmhObj[item] = _.difference(commonAlarmhList, useAlarmhData)
        })
      }

      // 保存点位
      const params = {
        ucloudBoxNum: this.driverParams.ucloudBoxNum,
        gatewayId: this.driverParams.gatewayId,
        edgeDriverId: this.driverConfigData.edgeDriverId,
        subDeviceId: this.driverParams.subDeviceId,
        productId: this.driverParams.productId,
        boxNum: this.driverParams.boxNum,
        pointList: []
      }
      params.pointList = this.tableData.map(item => {
        const resultObj = {
          addr: item.addr,
          repType: item.repType,
          serviceTypeId: item.serviceTypeId,
          deviceNum: item.deviceNum,
          deviceId: item.deviceId,
          dataType: item.dataType,
          productId: item.productId,
          repName: item.repName,
          relaPoint: item.relaPoint
        }
        // 如果是实时数据，且有未用的点位
        const commonPointList = commonPointObj[item.deviceId]
        if (item.repType === '4' && commonPointList?.length > 0 && !resultObj.relaPoint) {
          resultObj.relaPoint = commonPointList.shift()
        }

        const commonAlarmlList = commonAlarmlObj[item.deviceId]
        if (item.repType === '3' && item.serviceTypeId === 'L' && commonAlarmlList?.length > 0 && !resultObj.relaPoint) {
          resultObj.relaPoint = commonAlarmlList.shift()
        }

        const commonAlarmhList = commonAlarmhObj[item.deviceId]
        if (item.repType === '3' && item.serviceTypeId === 'H' && commonAlarmhList?.length > 0 && !resultObj.relaPoint) {
          resultObj.relaPoint = commonAlarmhList.shift()
        }
        return resultObj
      })
      this.submitting = true
      try {
        await plcPointConfigSet(params)
        await plcDeviceBindPoint(params.pointList)
        this.$emit('successSubmit', this.newDeviceIds)
      } finally {
        this.submitting = false
      }
    },

    changeDeviceType (data) {
      this.deviceTypeOptions = data
    },
    changeDeviceIds (data) {
      this.newDeviceIds = data
    },
    // 新建或者编辑
    createOrEdit (type, form) {
      this.$refs.addEditPointDialog.showDialog(form, type)
    },
    // 关闭dialog
    hideDialog () {
      this.$emit('hideDialog')
    },
    // 改变
    changeTableData (val) {
      this.tableData = val
    },
    // 跳过绑定
    skipBind () {
      this.$q.dialog({
        title: `<p class="dialog-notice-title"><i class="iconfont icontubiao-28"></i>
          确定要跳过此步骤吗？</p>`,
        html: true,
        ok: {
          unelevated: true,
          label: '确认'
        },
        cancel: {
          unelevated: true,
          outline: true,
          label: '取消'
        }
      }).onOk(() => {
        this.$emit('bindNone')
      })
    }
  }
}
</script>

<style scoped lang="scss">
.detail-container{
  padding: 20px;
  font-size: 14px;
  line-height: 1;
}
</style>
